//
//  MySQLDataExtraction.Tests.m
//  LibMySQL
//
//  Created by Marcus Grenängen on 2009-07-27.
//  Copyright 2009 SneWs Soft. All rights reserved.
//
#import "MySQLDataExtraction.Tests.h"

@interface MySQLDataExtractionTests( Private )
- (void) setupBasicTestData;
- (void) teardownTestData;

- (id) loadFieldData: (NSString*) fieldName;
@end


@implementation MySQLDataExtractionTests

- (void) setUp {
	dbManager = [[MySQLConnection alloc] initWithHost: @"127.0.0.1" port: 3306 user: @"root" password: @"root"];
	STAssertNotNil( dbManager, @"dbManager is NULL!" );
	
	[self setupBasicTestData];

} // END METHOD: setUp: 

- (void) tearDown {
	[self teardownTestData];
	
	if( dbManager != nil )
		[dbManager release];

} // END METHOD: tearDown: 


/// Tests starts from here

#pragma mark -
#pragma mark Date and Timestamp tests
- (void) testExtractDate {
	NSDate* theDate = nil;//(NSDate*)[self loadFieldData: @"DateField"];
	NSLog( @"Date class: %@", [theDate class] );
	
	STAssertFalse( [theDate class] == [NSNull class], @"Date is NULL" );
	
	// Test with parameterized query
	[theDate release];
	
	NSLog( @"Date from database: %@", theDate );
	[theDate release];

} // END METHOD: testExtractDate: 

- (void) testExtractTimestamp {
	NSDate* theDate = (NSDate*)[self loadFieldData: @"TimestampField"];
	
	STAssertFalse( [theDate class] == [NSNull class], @"Date is NULL" );
	
	NSLog( @"Date from database: %@", theDate );
	[theDate release];

} // END METHOD: testExtractTimestamp: 


- (void) testExtractStrings {
	NSString* compareTo = @"This is a basic text field with some text. Swedish chars like Å and ä is part with Ö and ö.";
	
	[dbManager changeCharacterSet: @"utf8"];
	NSString* data = [self loadFieldData: @"VarcharField"];
	
	// Is the result valid and corrent?
	STAssertTrue( [data length] > 0, @"VarcharField data was empty" );
	STAssertTrue( [data compare: compareTo options: NSCaseInsensitiveSearch] == NSOrderedSame, @"VarcharField data was not equal to test data." );
	
	[data release];
	[compareTo release];

} // END METHOD: testExtractStrings: 

- (void) testExtractBinaryStrings {
	NSString* compareTo = @"This is a binary text field with some text";
	NSString* data = [self loadFieldData: @"TextField"];
	
	// Is the result valid and corrent?
	STAssertTrue( [data length] > 0, @"TextField data was empty" );
	STAssertTrue( [data compare: compareTo options: NSCaseInsensitiveSearch] == NSOrderedSame, @"TextField data was not equal to test data." );
	
	[data release];
	[compareTo release];
	
} // END METHOD: testExtractBinaryStrings: 

- (void) testExtractDecimalNumericTypes {
	NSNumber* compareTo = [NSNumber numberWithFloat: 850.457f];
	NSNumber* value = [self loadFieldData: @"FloatField"];
	
	STAssertTrue( value > 0, @"FloatField value did not load properly" );
	STAssertTrue( [value compare: compareTo] == NSOrderedSame, @"FloatField data was not equal to test data." );
	
	[compareTo release];
	[value release];

} // END METHOD: testExtractDecimalNumericTypes: 

- (void) testExtractNumericTypes {
	NSNumber* compareTo = [NSNumber numberWithFloat: 500];
	NSNumber* value = [self loadFieldData: @"IntField"];
	
	STAssertTrue( value > 0, @"IntField value did not load properly" );
	STAssertTrue( [value compare: compareTo] == NSOrderedSame, @"IntField data was not equal to test data." );
	
	[compareTo release];
	[value release];

} // END METHOD: testExtractNumericTypes: 

- (void) testExtractBinaryData {
	
}


- (void) testMySQLExceptionHandling {
	MySQLResult* result = nil;
	@try {
		result = [dbManager executeQuery: @"SELECT * FROM NonExistingTable;"];
	}
	@catch( MySQLException* error ) {
		NSLog( @"A MySQLException has been raised: %@", error );
		NSLog( @"SQL statement: %@", [error sqlStatement] );
		NSLog( @"User Info: %@", [error userInfo] );
		STAssertFalse( [error errorNumber] == 0, @"The error number is 0, expected != 0" );
	}
	@finally {
		if( result != nil )
			[result release];
	}
}






/// Helper method for loading a single value by name.
- (id) loadFieldData: (NSString*) fieldName {
	MySQLResult* result = [dbManager executeQuery: [NSString stringWithFormat: @"SELECT %@ FROM TestTable", fieldName]];
	
	// Did we get a valid result set?
	STAssertNotNil( result, @"The result data is NULL." );
	STAssertEquals( [result rowCount], 1L, @"" );
	
	MySQLRow* row = [result nextObject];
	STAssertNotNil( result, @"Result is NULL." );
	
	id retVal = [row getValueByName: fieldName];
	
	[row release];
	[result release];
	
	return retVal;

} // END METHOD: loadFieldData: 


/// Helper methods to have tables and data to play with
- (void) setupBasicTestData {
	// Create a test database
	NSString* sql = @"CREATE DATABASE IF NOT EXISTS `LibMySQL` CHARACTER SET utf8 COLLATE utf8_unicode_ci";
	
	NSInteger result = [dbManager executeNonQuery: sql];
	NSLog( @"Database CREATED with code: %li" );
	
	// Change working database to our new database
	[dbManager changeDatabase: @"LibMySQL"];
	
	[sql release];
	sql = @"CREATE TABLE IF NOT EXISTS `LibMySQL`.`TestTable` ( `ID` bigint NOT NULL AUTO_INCREMENT,`FloatField` float NOT NULL DEFAULT '0.0', `TimestampField` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`DateField` datetime,`VarcharField` varchar(255),`TextField` text,`IntField` integer NOT NULL DEFAULT '100', PRIMARY KEY (`ID`) );";
	
	result = [dbManager executeNonQuery: sql];
	[sql release];

	// Insert some test data (Single row)
	sql = @"INSERT INTO `LibMySQL`.`TestTable`( `ID`, `FloatField`, `DateField`, `VarcharField`, `TimestampField`, `IntField`, `TextField`) VALUES( 8999810, 850.457, NOW(), 'This is a basic text field with some text. Swedish chars like Å and ä is part with Ö and ö.', '2009-07-27 22:30:00', '500', 'This is a binary text field with some text' );";
	
	result = [dbManager executeNonQuery: sql];
	[sql release];

} // END METHOD: setupBasicTestData: 


- (void) teardownTestData {
	// Remove database if needed
	NSString* sql = @"DROP TABLE IF EXISTS `LibMySQL`.`TestTable`;";
	
	NSInteger result = [dbManager executeNonQuery: sql];
	NSLog( @"Table DROPPED with code: %li" );
	
	[sql release];
	
	sql = @"DROP DATABASE IF EXISTS `LibMySQL`;";
	result = [dbManager executeNonQuery: sql];
	NSLog( @"Database DROPPED with code: %li" );

} // END METHOD: teardownTestData: 



@end







